              <div align="right">
${TARGET="offline"}                <a href="${LDAP_SDK_HOME_URL}" style="font-size: 85%">LDAP SDK Home Page</a>
${TARGET="offline"}                <br>
                <a href="${BASE}index.${EXTENSION}" style="font-size: 85%">Product Information</a>
                <br>
                <a href="index.${EXTENSION}" style="font-size: 85%">Advantages of the LDAP SDK</a>
              </div>

              <h2>Support for Java SE 5 Features</h2>

              <p>
                The UnboundID LDAP SDK for Java was written from the ground up to utilize the
                advantages that Java SE 5 and later releases offer over earlier versions.  It is
                true that this means it is not possible to use the UnboundID LDAP SDK for Java with
                Java SE versions 1.4 or earlier, but Java SE 5 has been available for several years
                on virtually every major operating system and offers significant advantages over
                earlier releases.  In addition, code written for earlier Java releases should work
                flawlessly (with or without recompilation) on Java 5, so making legacy code work in
                a Java SE 5 environment should not require any effort.
              </p>

              <p>
                JNDI is part of the core Java platform and therefore has been updated to take
                advantage of some of the new features of recent Java releases (primarily in the
                form of updating collections to use generics), although much of the legacy code is
                still using outdated functionality.  For example, the fact that it is still
                necessary to use <tt>Hashtable</tt> instances to define the environment properties
                is mind-boggling when much better alternatives have been available for a very long
                time, and at the very least a general-purpose <tt>Map</tt> could be used instead.
              </p>

              <p>
                The Netscape Directory SDK for Java was originally developed in the Java 1.1 time
                frame and does not appear to make use of any enhancements offered by recent Java
                releases.
              </p>

              <p></p>
              <h3>Generics</h3>

              <p>
                One of the most visible and useful changes that Java SE 5 offers over earlier
                releases is the addition of generics.  This makes it possible to provide improved
                type safety when dealing with many kinds of objects.
              </p>

              <p>
                For example, with earlier Java releases, a method that returned a list of
                <tt>Entry</tt> objects would have used a return type of "<tt>List</tt>".  This had
                the following disadvantages:
              </p>

              <ul>
                <li>
                  The Java compiler had no idea what was supposed to be placed in that list, and
                  would allow any type of object to be included.
                  <br><br>
                </li>
                <li>
                  The javadoc tool had no idea what was supposed to be placed in that list, and
                  would not automatically include any information in the generated documentation to
                  indicate what type of data it contained.
                  <br><br>
                </li>
                <li>
                  Whenever items were accessed in the list, they were treated as generic
                  <tt>Object</tt> elements and had to be explicitly typecast to the appropriate
                  type of object.
                  <br><br>
                </li>
              </ul>

              <p>
                With the introduction of generics, however, it is now possible to specify a return
                type of "<tt>List&lt;Entry&gt;</tt>".  This means that the compiler will complain
                any time there is an attempt to put something in that list that is not (or might
                not be) an <tt>Entry</tt> object.  The generated javadoc documentation will also
                show the return type as "<tt>List&lt;Entry&gt;</tt>" so developers using the code
                will know what type of objects are held in that list, and furthermore those objects
                can be directly treated as <tt>Entry</tt> objects without the need to perform any
                typecasting.
              </p>

              <p>
                The UnboundID LDAP SDK for Java uses generics for all types of collections used in
                the code.  This offers greater type safety for the SDK code itself, and makes it
                easier and more convenient for developers using the SDK to interact with those
                collections.
              </p>

              <p></p>
              <h3>Varargs</h3>

              <p>
                The varargs capability added in Java SE 5 makes it possible to indicate that a
                method may take any number of objects of a given type as arguments.  A varargs
                placeholder may only be used as the last element in the argument list, and the Java
                compiler will automatically convert it to an array of that type of object.
              </p>

              <p>
                For example, consider the following constructor for the
                <tt>com.unboundid.ldap.sdk.Attribute</tt> class:
              </p>

              <pre>
Attribute(String name, String... values)
</pre>

              <p>
                This makes it possible to specify multiple values as a comma-separated list of
                strings instead of requiring them to be first placed in an array.  This is purely a
                convenience feature, and it means that the following two calls have exactly the
                same result:
              </p>

              <ul>
                <li>
                  <tt>new Attribute("myAttribute", "firstValue", "secondValue", "thirdValue")</tt>
                  <br><br>
                </li>
                <li>
                  <tt>new Attribute("myAttribute", new String[] { "firstValue", "secondValue", "thirdValue" })</tt>
                  <br><br>
                </li>
              </ul>

              <p>
                Wherever it makes sense to do so, the UnboundID LDAP SDK for Java uses varargs so
                that developers using the SDK have the option of providing those values either
                individually or in an array.
              </p>

              <p></p>
              <h3>Enumerations</h3>

              <p>
                Java enumerations are objects which have a fixed set of well-known, immutable
                values.  The UnboundID LDAP SDK for Java uses enumerations in a few key places,
                including:
              </p>

              <ul>
                <li>
                  The usage types that may appear in an attribute type definition.
                  <br><br>
                </li>
                <li>
                  The kind values that may appear in an object class definition.
                  <br><br>
                </li>
                <li>
                  The change types that may be used in persistent search and entry change
                  notification controls.
                  <br><br>
                </li>
                <li>
                  The warning and error types that may be used in the password policy control
                  defined in draft-behera-ldap-password-policy.
                  <br><br>
                </li>
                <li>
                  The state values that a scheduled task may have.
                  <br><br>
                </li>
                <li>
                  The failed dependency action that might be defined for a task.
                  <br><br>
                </li>
                <li>
                  The available categories for SDK debugging information.
                  <br><br>
                </li>
              </ul>

              <p>
                Note that there are a few notable instances within the SDK in which enumerations
                could have been used but were not in order to provide greater compatibility and to
                allow them to be more future-proof.  Those cases include:
              </p>

              <ul>
                <li>
                  Result codes.  It is likely that the set of LDAP result codes will be expanded in
                  the future, and the LDAP SDK must be able to handle result codes that it does not
                  currently know anything about.
                  <br><br>
                </li>
                <li>
                  Search scope values.  It is possible that the set of possible search scopes may
                  be expanded in the future (as has been proposed with the subordinate subtree
                  scope in draft-sermersheim-ldap-subordinate-scope) without requiring any
                  additional client-side code changes.
                  <br><br>
                </li>
                <li>
                  Modification type values.  It is possible that the set of possible modification
                  types may be expanded in the future (as was recently done with the modify
                  increment extension in RFC 4525) without requiring additional client-side code
                  changes.
                  <br><br>
                </li>
                <li>
                  Dereference policy values.  It is possible that the set of alias dereference
                  policies may be expanded in the future without requiring additional client-side
                  code changes.
                  <br><br>
                </li>
              </ul>

              <p>
                In each of these cases, there are constants available for the currently-defined
                values (in the <tt>ResultCode</tt>, <tt>SearchRequest</tt>, <tt>Modification</tt>,
                and <tt>SearchRequest</tt> classes, respectively), but if a new specification
                arises in the future that defines a new value for any of these elements, the
                UnboundID LDAP SDK will allow that value to be utilized without requiring the SDK
                itself to be modified.
              </p>

              <p></p>
              <h3>Concurrency Utilities</h3>

              <p>
                Java SE 5 includes a new <tt>java.util.concurrent</tt> package structure with
                objects that are intended to provide safe, high-performance processing when
                accessed concurrently by multiple threads.  Areas in which concurrent API elements
                were used include:
              </p>

              <ul>
                <li>
                  <tt>AtomicInteger</tt> or <tt>AtomicLong</tt> objects are used in cases where an
                  incrementing integer value may be required (e.g., message IDs for LDAP request
                  messages).
                  <br><br>
                </li>
                <li>
                  <tt>LinkedBlockingQueue</tt> objects are used in several places where one thread
                  is waiting to be given an object from another thread.
                  <br><br>
                </li>
                <li>
                  <tt>ConcurrentHashMap</tt> objects are used in cases where a highly-concurrent
                  and threadsafe map is required.
                  <br><br>
                </li>
              </ul>

              <p>
                Using these concurrent objects allows for better performance and scalability for
                objects that need threadsafe access than was previously possible to achieve.
              </p>

              <p></p>
              <h3>Other Java 5 Improvements</h3>

              <p>
                The <tt>StringBuilder</tt> class introduced in Java SE 5 is virtually identical to
                the earlier <tt>StringBuffer</tt> class, with the exception that
                <tt>StringBuilder</tt> objects are not synchronized while <tt>StringBuffer</tt>
                objects are (and are therefore slower in code where contention isn't a concern).
                The UnboundID LDAP SDK for Java uses <tt>StringBuilder</tt> objects in several
                places throughout the code where a <tt>StringBuffer</tt> object might have been
                used in earlier releases.
              </p>

              <p>
                Another new feature added in Java SE 5 is that of annotations.  Annotations can be
                used to associate metadata with Java code elements like classes, methods, and
                fields.  The UnboundID LDAP SDK for Java itself does not define any new annotations
                at this time, although it does make use of existing Java annotations (like
                "<tt>@Override</tt>") when it makes sense to do so.  Further, the unit test code
                for the SDK uses the TestNG framework, which makes heavy use of annotations.
              </p>
